﻿using Mapster;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using WH.Contracts.Select;
using WH.Contracts.Systems.Menus;
using WH.Model.Systems;
using WH.Services.IServices.ISystem;
using Rw.Core.Common;
using Rw.Core.Common.Extensions;
using Rw.Core.Common.Paging;
using WH.Common.Constant;
using WH.Common.Paging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace WH.WebApi.Controllers.Systems
{
    /// <summary>
    /// 菜单信息说明表接口
    /// </summary>
    [Authorize, Route("Menus"), ApiController]
    public class MenusController : BaseController
    {
        private readonly IMenuService _menuService;
        private readonly IRolePermissionService _rolePermissionService;
        private readonly IOrganizationService _organizationService;

        /// <summary>
        /// 菜单
        /// </summary>
        public MenusController(IMenuService menuService, IOrganizationService organizationService, IRolePermissionService rolePermissionService)
        {
            _menuService = menuService;
            _organizationService = organizationService;
            _rolePermissionService = rolePermissionService;
        }

        /// <summary>
        /// 根据菜单id获取菜单
        /// </summary>
        /// <param name="id">菜单Id</param>
        /// <returns></returns>
        [HttpGet("{id}")]
        public async Task<ResultResponse<MenuOutputDto>> GetMenuByIdAsync(string id)
        {
            var result = new ResultResponse<MenuOutputDto>();
            try
            {
                var menu = await _menuService.FindByIdAsync(id);

                if (menu == null)
                {
                    result.IsSucceed = false;
                    result.Msg = "未查找到该菜单，请重新操作";
                    return result;
                }

                result.Data = result.Adapt<MenuOutputDto>();

                result.IsSucceed = true;
                result.Msg = "查询成功";
            }
            catch (Exception)
            {
                result.IsSucceed = false;
                result.Msg = "未查找到该菜单，请重新操作";
            }

            return result;
        }

        /// <summary>
        /// 添加菜单
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("")]
        public async Task<ResultResponse> PostAsync([FromBody] MenuInputDto input)
        {
            var result = new ResultResponse();
            try
            {
                if (!ModelState.IsValid)
                {
                    result.IsSucceed = false;
                    result.Msg = "参数异常，请重新输入";
                    return result;
                }

                //var exist = await menuRepository.ExistsAsync(a => a.Redirect == input.Redirect && !string.IsNullOrEmpty(a.Redirect));
                //if (exist)
                //{
                //    result.IsSucceed = false;
                //    result.Msg = "请确保菜单编号唯一，请重新操作";
                //    return result;
                //}

                var id = Snowflake.GetNewId();

                if (input.ParentId != "0")
                {
                    if (!string.IsNullOrWhiteSpace(input.ParentId))
                    {
                        var parent = await _menuService.FindByIdAsync(input.ParentId);
                        if (parent == null)
                        {
                            result.IsSucceed = false;
                            result.Msg = "上级菜单不存在，请重新操作";
                            return result;
                        }

                        await _menuService.UpdateAsync(parent);
                    }
                }


                var menu = input.Adapt<MenuEntity>();
                menu.Id = id;

                var res = await _menuService.CreateAsync(menu);

                if (LoginDto.IsAdmin == false)
                {
                    var rolePermission = new RolePermissionEntity
                    {
                        Id = Snowflake.GetNewId(),
                        RoleType = 1,
                        RoleId = LoginDto.RoleId,
                        ResourceId = menu.Id,
                        ResourceType = menu.MenuType,
                        OrganizationId = OrganizationId,
                        IsEnable = true,
                    };
                    await _rolePermissionService.CreateAsync(rolePermission);
                }

                result.IsSucceed = res > 0;
                result.Msg = res > 0 ? "添加成功" : "添加失败";
            }
            catch (Exception ex)
            {
                result.IsSucceed = false;
                result.Msg = ex.Message;
            }
            return result;
        }

        /// <summary>
        /// 编辑菜单
        /// </summary>
        /// <param name="id"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPut("{id}")]
        public async Task<ResultResponse> PutAsync(string id, [FromBody] MenuInputDto input)
        {
            if (input.Id == input.ParentId)
            {
                return Error("不能将自身作为父级节点，请检查");
            }

            var menu = await _menuService.FindByIdAsync(id);
            if (menu is null)
            {
                return Error("未查找到该菜单，请重新操作");
            }
            if (input.ParentId != BusinessFunction.TopParentId)
            {
                var parent = await _menuService.FindByIdAsync(input.ParentId);
                if (parent == null)
                {
                    return Error("上级菜单不存在，请重新操作");
                }
            }

            var menuUpdate = input.Adapt<MenuEntity>();

            var res = await _menuService.UpdateAsync(menuUpdate);

            return res > 0 ? Success() : Error();
        }

        /// <summary>
        ///菜单删除
        /// </summary>
        /// <param name="id">主键集合</param>
        /// <returns></returns>
        [HttpDelete("{id}")]
        public async Task<ResultResponse> DeleteAsync(string id)
        {
            var menu = await _menuService.FindByIdAsync(id);
            if (menu == null)
            {
                return Error("此菜单不存在");
            }

            var hasChildren = await _menuService.ExistsAsync(a => a.ParentId == menu.Id);
            if (hasChildren)
            {
                return Error("请先删除此菜单下的子菜单，再删除此菜单");
            }

            //if (!string.IsNullOrWhiteSpace(menu.ParentId))
            //{
            //    var parent = await menuRepository.FindByIdAsync(menu.ParentId);
            //    if (parent != null)
            //    {
            //        var parentHasChildren = await menuRepository.AnyAsync(o => o.ParentId == parent.Id && o.Id != menu.Id);
            //        parent.IsLeaf = !parentHasChildren;
            //        await menuRepository.UpdateAsync(parent);
            //    }
            //}

            var res = await _menuService.RemoveAsync(menu);

            return res > 0 ? Success() : Error();

        }


        /// <summary>
        /// 菜单列表数据
        /// </summary>
        /// <param name="filter">查询实体参数请求</param>
        /// <returns></returns>
        [HttpGet("")]
        public async Task<ResultResponse<IList<MenuOutputDto>>> GetMenusAsync([FromQuery] MenuFilterDto filter)
        {
            var filterData = new MenuFilter();
            if (filter != null)
            {
                filterData.Keyword = filter.Keyword;
                filterData.Code = filter.Code;
                filterData.Name = filter.Name;
                filterData.OrganizationId = filter.OrganizationId;
                filterData.Status = filter.Status;
            }

            var res = await _menuService.GetMenusAsync(filterData);


            return Success<IList<MenuOutputDto>>(res);
        }

        /// <summary>
        /// 菜单列表分页数据
        /// </summary>
        /// <param name="pager">分页</param>
        /// <param name="filter">查询实体参数请求</param>
        /// <returns></returns>
        [HttpGet("page")]
        public async Task<ResultResponse<IPagedList<MenuOutputDto>>> GetMenusByPageAsync([FromQuery] PageParam pager, [FromQuery] MenuFilterDto filter)
        {
            var filterData = new MenuFilter();
            if (filter != null)
            {
                filterData.Keyword = filter.Keyword;
                filterData.Code = filter.Code;
                filterData.Name = filter.Name;
                filterData.OrganizationId = filter.OrganizationId;
                filterData.Status = filter.Status;
            }

            var res = await _menuService.GetMenusByPageAsync(pager, filterData);

            return Success(res);
        }

        /// <summary>
        /// 菜单列表数据
        /// </summary>
        /// <param name="parentId">查询实体参数请求</param>
        /// <returns></returns>
        [HttpGet("Tree/{parentId}")]
        public async Task<ResultResponse<IList<MenuOutputDto>>> GetMenusByTreeWithParentIdAsync(string parentId)
        {
            var list = await _menuService.FindAllAsync(o => o.ParentId == parentId);
            var data = list.Adapt<IList<MenuOutputDto>>();

            var orgIds = data.Select(m => m.OrganizationId).Distinct().ToList();
            var orgs = await _organizationService.FindAllAsync(o => orgIds.Contains(o.Id));
            foreach (var map in data)
            {
                var org = orgs.FirstOrDefault(o => o.Id == map.OrganizationId);
                if (org != null)
                {
                    map.OrganizationName = org.Name;
                }
            }
            return Success(data);
        }


        /// <summary>
        /// 下拉列表数据
        /// </summary>
        /// <param name="organizationId"></param>
        /// <returns></returns>
        [HttpGet("Select")]
        public async Task<ResultResponse<IList<OutputBySelectDto>>> GetMenusBySelectAsync([FromQuery] string organizationId)
        {
            Expression<Func<MenuEntity, bool>> expression = d => d.Status;
            if (!string.IsNullOrWhiteSpace(organizationId))
            {
                organizationId = organizationId.Trim();
                expression = expression.And(d => organizationId == d.OrganizationId);
            }

            var list = await _menuService.FindAllAsync(expression);

            IList<OutputBySelectDto> data = list.Select(o => new OutputBySelectDto
            {
                Id = o.Id,
                Name = o.Name,
                ParentId = o.ParentId,
            }).ToList();

            return Success(data);
        }

        /// <summary>
        /// 获取所有Id
        /// </summary>
        /// <param name="list"></param>
        /// <param name="parentId"></param>
        /// <returns></returns>
        private IList<string> GetChildIds(IList<MenuOutputDto> list)
        {
            if (list is null)
            {
                return default;
            }
            var ids = list.Select(x => x.Id).ToList();
            foreach (var item in list)
            {
                if (item.Children is not null)
                {
                    ids.AddRange(GetChildIds(item.Children));
                }
            }

            return ids;
        }
    }
}